﻿using System;
using System.Collections.Generic;
using System.Text;
using JsonSharp;
using Barbar.MapReport.Common.Drawing.Commands;
using JsonSharp.Collections;
using JsonSharp.Values;
using Barbar.MapReport.Common;

namespace Barbar.MapReport.HtmlRender.Json {
  internal class GeoLineFactory : JsonFactory {
    private GeoLine m_Line;

    public GeoLineFactory(GeoLine line) {
      m_Line = line;
    }

    public override JsonValue ToJsonObject() {
      JsonObjects result = new JsonObjects();
      result.Add(new JsonStringValue("startPoint"), new GeoPointFactory(m_Line.StartPoint).ToJsonObject());
      result.Add(new JsonStringValue("endPoint"), new GeoPointFactory(m_Line.Endpoint).ToJsonObject());
      result.Add(new JsonStringValue("width"), new JsonNumberValue(m_Line.Width));
      result.Add(new JsonStringValue("color"), new JsonColorValue(m_Line.SerializedColor.Color));
      result.Add(new JsonStringValue("opacity"), new JsonNumberValue(m_Line.SerializedColor.Color.A / 255.0));
      JsonArrays arrayCollection = new JsonArrays();

      for (int i = 0; i < 18; i++) {
        MercatorProjection projection = new MercatorProjection(i);
        JsonArrays arrowPoints = new JsonArrays();
        arrayCollection.Add(arrowPoints);

        PointD start = projection.ToPointD(m_Line.StartPoint);
        PointD end = projection.ToPointD(m_Line.Endpoint);
        VectorD vector = end - start;
        int arrowLength = Math.Min(25, m_Line.Width * 3);
        if (vector.Length < m_Line.Offset + arrowLength * 2) {
          continue;
        }

        VectorD normal = vector.NormalVector.UnitVector;
        vector = vector.UnitVector;

        PointD arrowTop = end + (vector * m_Line.Offset);
        PointD arrowBase = end + (vector * (m_Line.Offset + arrowLength * 2));

        PointD arrowLeft = arrowBase + (normal * (arrowLength / 2));
        PointD arrowRight = arrowBase + (normal * (-arrowLength / 2));

        PointD[] points = new PointD[] { arrowTop, arrowLeft, arrowRight };
        foreach (PointD point in points) {
          arrowPoints.Add(new GeoPointFactory(projection.ToGeoPoint(point)).ToJsonObject());
        }
      }
      result.Add(new JsonStringValue("arrows"), arrayCollection);
      return result;
    }
  }
}
